<template>
  <div>
    <el-row>
      <slot />
    </el-row>
    <el-form
      ref="form"
      :model="form"
      :rules="rules"
      autocomplete="on"
      label-position="right"
      label-width="110px"
    >
      <div v-for="item in fields" :key="item.colName">
        <el-form-item
          v-if="!(item.colName==='id' && editType==='add') && item.hiddenIn !== editType"
          :label="item.displayName"
          :prop="item.colName"
        >
          
          <!-- 数字 -->
          <el-input
            v-if="item.dataType==='number'"
            v-model.number="form[item.colName]"
            :readonly="item.readOnly||readonly"
            :disabled="item.disabled||disabled"
            :type="item.dataType"
          />
          <!-- 开关 -->
          <el-checkbox
            v-else-if="item.dataType==='bool'"
            v-model="form[item.colName]"
            :readonly="item.readOnly||readonly"
            :disabled="item.disabled||disabled"
          />
          <!-- 选择 -->
          <el-select
            v-else-if="item.dataType==='select'"
            v-model="form[item.colName]"
            :filterable="true"
            :readonly="item.readOnly||readonly"
            :disabled="item.disabled||disabled"
            @change="onSelectChange(item, form)"
          >
            <el-option
              v-for="opt in item.data.options"
              :key="opt.value"
              :label="opt.name"
              :value="opt.value"
            />
          </el-select>
          <!-- 从面板中选择 -->
          <select-panel
            v-else-if="item.dataType==='selectPanel'"
            v-model="form[item.colName]"
            :filterable="true"
            :readonly="item.readOnly||readonly"
            :disabled="item.disabled||disabled"
            :item="item"
            :parent-form="form"
            @valueChange="onInputListChange"
          />
          <!-- 选择，但是带扩展信息 -->
          <div v-else-if="item.dataType==='selectEx'">
            <el-select
              v-model="form[item.colName]"
              :filterable="true"
              :readonly="item.readOnly||readonly"
              :disabled="item.disabled||disabled"
              @change="onSelectChange(item, form)"
            >
              <el-option
                v-for="opt in item.data.options"
                :key="opt.value"
                :label="opt.name"
                :value="opt.value"
              />
            </el-select>
            <span v-if="typeof item.data.note[editType] === 'object'" style="margin-left: 10px;">
              <el-tag
                v-if="item.data.note[editType].type==='text'"
                type="info"
                effect="plain"
              >
                {{ item.data.note[editType].label }}
              </el-tag>
              <el-button
                v-if="item.data.note[editType].type==='button'"
                type="primary"
                size="mini"
                @click="item.data.note[editType].onclick(form, item)"
              >
                {{ item.data.note[editType].label }}
              </el-button>
            </span>
          </div>
          <!-- 从api选择 -->
          <from-api
            v-else-if="item.dataType==='fromapi'"
            v-model="form[item.colName]"
            :apiname="item.data.name"
            :readonly="item.readOnly||readonly"
            :disabled="item.disabled||disabled"
          >
            <el-button
              v-if="item.withCreateButton"
              type="primary"
              size="mini"
              style="marin-left: 5px;"
              @click="item.withCreateButton.onclick({item, form})"
            >
              {{ item.withCreateButton.name }}
            </el-button>
          </from-api>
          <!-- 从带分页的api选择 -->
          <from-api-page
            v-else-if="item.dataType==='fromapipage'"
            v-model="form[item.colName]"
            :apiname="item.data.name"
            :readonly="item.readOnly||readonly"
            :disabled="item.disabled||disabled"
            :query-with="getQueryWith(item, form)"
          >
            <el-button
              v-if="item.withCreateButton"
              type="primary"
              size="mini"
              style="margin-left: 5px;"
              @click="item.withCreateButton.onclick({item, form})"
            >
              {{ item.withCreateButton.name }}
            </el-button>
          </from-api-page>
          <!-- 联合选择省市 -->
          <el-cascader
            v-else-if="item.dataType==='combineProvinceAndCity'"
            v-model="form[item.colName]"
            :options="provinceOptions"
            placeholder="请选择省市"
            @change="arr=>addressChange(item,arr)"
          />
          <!-- QQ Map -->
          <qq-map
            v-else-if="item.dataType==='qqMap'"
            v-model="form[item.colName]"
            :itemfield="item"
            :form="form"
            :readonly="item.readOnly||readonly"
            :disabled="item.disabled||disabled"
            @select="qqMapSelected"
          />
          <!-- 选择省份 -->
          <el-select
            v-else-if="item.dataType==='selProvince'"
            v-model="form[item.colName]"
            placeholder="请选择省份"
            :filterable="true"
            :readonly="item.readOnly||readonly"
            :disabled="item.disabled||disabled"
            @change="onProvinceSelect(item, form)"
          >
            <el-option
              v-for="opt in provinceList"
              :key="opt"
              :label="opt"
              :value="opt"
            />
          </el-select>
          <!-- 选择市 -->
          <el-select
            v-else-if="item.dataType==='selCity'"
            v-model="form[item.colName]"
            placeholder="请选择城市"
            :filterable="true"
            :readonly="item.readOnly||readonly"
            :disabled="item.disabled||disabled"
            @change="onCitySelect(item, form)"
          >
            <el-option
              v-for="opt in cityList"
              :key="opt"
              :label="opt"
              :value="opt"
            />
          </el-select>
          <!-- 选择区县 -->
          <el-select
            v-else-if="item.dataType==='selArea'"
            v-model="form[item.colName]"
            placeholder="请选择区县"
            :filterable="true"
            :readonly="item.readOnly||readonly"
            :disabled="item.disabled||disabled"
          >
            <el-option
              v-for="opt in areaList"
              :key="opt"
              :label="opt"
              :value="opt"
            />
          </el-select>
          <!-- 省编号 -->
          <el-input
            v-else-if="item.dataType==='provinceCode'"
            v-model.number="form[item.colName]"
            :readonly="item.readOnly||readonly"
            :disabled="item.disabled||disabled"
            :type="item.dataType"
          />
          <!-- 市编号 -->
          <el-input
            v-else-if="item.dataType==='cityCode'"
            v-model.number="form[item.colName]"
            :readonly="item.readOnly||readonly"
            :disabled="item.disabled||disabled"
            :type="item.dataType"
          />
          <!-- 地址，自动填充分项 -->
          <el-input
            v-else-if="item.dataType==='address'"
            v-model="form[item.colName]"
            :readonly="item.readOnly||readonly"
            :disabled="item.disabled||disabled"
            :type="item.dataType"
            @change="onAddressChanged(item, form)"
          />
          <!-- 带眼睛的password -->
          <div v-else-if="item.dataType==='password'">
            <el-input
              v-model="form[item.colName]"
              :readonly="item.readOnly||readonly"
              :disabled="item.disabled||disabled"
              :type="passwordType"
            />
            <span class="show-pwd" @click="showPwd(item)">
              <svg-icon :icon-class="passwordType === 'password' ? 'eye' : 'eye-open'" />
            </span>
          </div>
          <!-- 时间段 -->
          <el-time-picker
            v-else-if="item.dataType==='timeRange'"
            v-model="form[item.colName]"
            is-range
            format="HH:mm"
            value-format="HH:mm"
            range-separator="至"
            start-placeholder="开始时间"
            end-placeholder="结束时间"
            placeholder="选择时间范围"
          />
          <!-- 默认 -->
          <el-input
            v-else
            v-model="form[item.colName]"
            :readonly="item.readOnly||readonly"
            :disabled="item.disabled||disabled"
            :type="item.dataType"
            :placeholder="item.placeholder||'请填写'+item.displayName"
          />
        </el-form-item>
      </div>
      <el-form-item>
        <el-button v-if="!readonly" type="primary" @click="onSubmit">确定</el-button>
        <el-button @click="onCancel">取消</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>

<script>
import FromApi from "./fromapi.vue";
import FromApiPage from "./fromapipage.vue";
import QqMap from "./qqmap.vue";
import SelectPanel from "./selectPanel.vue";
import { default as ssqcode } from "./ssqcode";
import {
  provinceAndCityData,
  CodeToText,
  TextToCode,
} from "element-china-area-data";

export default {
  name: "CommonEdit",
  components: { FromApi, FromApiPage, QqMap, SelectPanel },
  props: {
    readonly: {
      type: Boolean,
      default: false,
    },
    disabled: {
      type: Boolean,
      default: false,
    },
    fields: {
      type: Array,
      default: function () {
        return [{ displayName: "...", colName: "aa" }];
      },
    },
    values: {
      type: Object,
      default: function () {
        return {};
      },
    },
    rules: {
      type: Object,
      default: function () {
        return {};
      },
    },
    editType: {
      type: String,
      default: "edit",
    },
  },
  data() {
    return {
      form: {},
      currentProvince: "",
      currentCity: "",
      ssq: {}, // 省市区
      provinceOptions: provinceAndCityData, // 省市联合
      local: {}, // 本地临时数据
      passwordType: "password",
    };
  },
  computed: {
    itemid() {
      return this.$route.params.id;
    },
    cname() {
      return this.$route.params.cname;
    },
    provinceList() {
      return Object.values(this.ssq[0] || {});
    },
    cityList() {
      return Object.values(this.ssq[this.currentProvince] || {});
    },
    areaList() {
      return Object.values(this.ssq[this.currentCity] || {});
    },
  },
  watch: {
    values(newValues) {
      this.form = Object.assign({}, newValues);
      if (this.values.provinceCode) {
        this.currentProvince = `0,${this.values.provinceCode}`;
        if (this.values.cityCode) {
          this.currentCity = `${this.currentProvince},${this.values.cityCode}`;
        }
      }
    },
  },
  mounted() {
    this.ssq = ssqcode;
    this.form = Object.assign({}, this.values);
    if (this.values.provinceCode) {
      this.currentProvince = `0,${this.values.provinceCode}`;
      if (this.values.cityCode) {
        this.currentCity = `${this.currentProvince},${this.values.cityCode}`;
      }
    }
  },
  methods: {
    getQueryWith(item, form) {
      if (item.data.queryWith) {
        return item.data.queryWith.map((val) => {
          return { name: val, value: form[val] };
        });
      }
    },
    onSubmit() {
      this.$refs["form"].validate((valid) => {
        if (valid) {
          this.$emit("onSubmit", this.form);
        } else {
          console.log("error validate", this.form);
          this.$message.error("表单内有错误，请检查修改后再提交！");
        }
      });
    },
    onCancel() {
      this.$emit("onCancel");
    },
    onProvinceSelect(item, form) {
      // console.log('onProvinceSelect')
      const ssq = this.ssq;
      const pv = Object.keys(ssq[0]).find(
        (k) => ssq[0][k] === form[item.colName]
      );
      if (pv) {
        this.currentProvince = `0,${pv}`;
      } else {
        this.currentProvince = "";
      }
      if (item.data && item.data.code) {
        // 更新省编号
        this.form[item.data.code] = parseInt(pv);
      }
    },
    onCitySelect(item, form) {
      // console.log('onCitySelect')
      const ssq = this.ssq;
      if (!this.currentProvince) return;
      const pv = this.currentProvince;
      const ct = Object.keys(ssq[pv]).find(
        (k) => ssq[pv][k] === form[item.colName]
      );
      if (ct) {
        this.currentCity = `${pv},${ct}`;
      } else {
        this.currentCity = "";
      }
      if (item.data && item.data.code) {
        // 更新市编号
        this.form[item.data.code] = parseInt(ct);
      }
    },
    onAddressChanged(item, form) {
      // 分解地址
      const val = form[item.colName];
      const re =
        /(中国)?((?<province>[^省]+省|.+自治区)|上海|北京|天津|重庆|香港|澳门)(?<city>[^市]+市|.+自治州)(?<county>[^县]+县|.+区|.+镇|.+局)?(?<town>[^区]+区|.+镇)?(?<village>.*)/g;
      const ma = [...val.matchAll(re)];
      // console.log('onAddressChanged:', val, ma)
      if (ma.length > 0 && ma[0].length > 5) {
        this.form[item.data.provinceCol] = ma[0][2];
        this.form[item.data.cityCol] = ma[0][4];
        this.form[item.data.areaCol] = ma[0][5];
        this.form.combineProvinceAndCity = [
          TextToCode[ma[0][2]] ? TextToCode[ma[0][2]].code : 0,
          TextToCode[ma[0][2]] && TextToCode[ma[0][2]][ma[0][4]]
            ? TextToCode[ma[0][2]][ma[0][4]].code
            : 0,
        ];
        this.form.qqMap = {
          province: ma[0][5],
          city: ma[0][4],
          address: val,
        };
      }
    },
    showPwd(item) {
      if (this.passwordType === "password") {
        this.passwordType = "";
      } else {
        this.passwordType = "password";
      }
    },
    addressChange(item, arr) {
      console.log(this.form);
      if (arr) {
        this.form[item.data.province.name] = CodeToText[arr[0]];
        this.form[item.data.city.name] = CodeToText[arr[1]];
      } else {
        this.form[item.data.province.name] = "";
        this.form[item.data.city.name] = "";
      }
      this.form.qqMap = {
        province: this.form[item.data.province.name],
        city: this.form[item.data.city.name],
      };
      console.log(
        "addressChange",
        arr,
        this.form[item.data.province.name],
        this.form[item.data.city.name]
      );
    },
    qqMapSelected({ info, item }) {
      Object.keys(item.data).forEach((key) => {
        if (info[key]) this.form[item.data[key].name] = info[key];
      });
      // const provinceCode = TextToCode[info.province] ? TextToCode[info.province].code : undefined
      // const cityCode = TextToCode[info.province] && TextToCode[info.province][info.city] ? TextToCode[info.province][info.city].code : undefined
      // this.form.combineProvinceAndCity = [
      //   provinceCode,
      //   cityCode
      // ]
    },
    onInputListChange({ item, form }) {
      this.form = Object.assign(this.form, form);
    },
    onSelectChange(item, form) {
      console.log("onSelectChange", item, form);
    },
  },
};
</script>

<style scoped>
.line {
  text-align: center;
}
.show-pwd {
  position: absolute;
  right: 10px;
  top: 0px;
  font-size: 16px;
  color: #889aa4;
  cursor: pointer;
  user-select: none;
}
</style>

